<template>
  <div class="tem-table">
    <div class="c-header">
      <div style="width: 240px">
        <el-input v-model="keyword" placeholder="请输入搜索关键词" clearable
                  @input="onKeywordChange" @clear="onClearKeyword"/>
      </div>
      &nbsp;&nbsp;
      <el-button type="primary" @click="onSearch">
        <el-icon>
          <Search/>
        </el-icon>&nbsp;搜索
      </el-button>
      <el-button type="default" @click="onReset">
        <el-icon>
          <RefreshLeft/>
        </el-icon>&nbsp;重置
      </el-button>
      <el-button type="success" @click="onNew">
        <el-icon>
          <Plus/>
        </el-icon>
        &nbsp;创建应用
      </el-button>
      &nbsp;&nbsp;
      <el-upload
          type="danger"
          name="file"
          :headers="{
                  'token': getAdminToken()
                }"
          :action="srvHost+'/srv-auth/upDownload/importSqlShell'"
          :multiple="false"
          :show-file-list="false"
          :before-upload="onImportSqlShellPre"
          :on-success="onImportSqlShellSucc"
          :on-error="onImportSqlShellErr"
      >
        <el-button type="danger">导入应用</el-button>
      </el-upload>
    </div>
    <div class="tem-table-box">
      <el-table v-loading="loading" height="100%" :data="tableData" border style="width: 100%">
        <el-table-column prop="id" label="应用ID" min-width="150"/>
        <el-table-column prop="appName" label="应用名称" min-width="100"/>
        <el-table-column prop="activeRule" label="匹配根路径" min-width="150"/>
        <el-table-column prop="frontIp" label="前端Ip" min-width="100"/>
        <el-table-column prop="frontPort" label="前端端口" min-width="70"/>
        <el-table-column prop="nginxBasePath" label="nginx根路径" min-width="100"/>
        <el-table-column prop="frontIp" label="服务端Ip" min-width="100"/>
        <el-table-column prop="serverPort" label="服务端端口" min-width="70"/>
        <el-table-column prop="appType" label="应用类型" min-width="70">
          <template #default="{row}">
            <span v-if="row.appType==='web'">PC端</span>
            <span v-else-if="row.appType==='h5'">手机H5</span>
            <span v-else-if="row.appType==='miniapp'">小程序</span>
            <span v-else>手机APP</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" min-width="120">
          <template #default="{ row }">
            <router-link :to="{path:'/authAppHome/appDetails', query:{appId:row.id}}">
              <el-button link type="success" size="small" @click="()=>store.pageTitle=row.appName">详情</el-button>
            </router-link>
            &nbsp;
            <el-button link type="primary" size="small" @click="onNew(row)">编辑</el-button>
            <el-button link type="danger" size="small" @click="onExportSettings(row.id, row.appName)">导出配置
            </el-button>
            <el-upload
                link
                type="danger"
                size="small"
                name="file"
                :headers="{
                  'token': getAdminToken()
                }"
                :action="srvHost+'/srv-auth/upDownload/importSqlShell'"
                :multiple="false"
                :show-file-list="false"
                :before-upload="onImportSqlShellPre"
                :on-success="onImportSqlShellSucc"
                :on-error="onImportSqlShellErr"
            >导入配置
            </el-upload>
            <el-button link type="danger" size="small" @click="onDel(row.id)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div style="display: flex; justify-content: flex-end; padding: 10px;">
      <el-pagination
          v-model:current-page="pageNo"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 30, 50]"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          background
          @size-change="handleSizeChange"
          @current-change="handleNoChange"
      />
    </div>
    <el-dialog width="500px" v-model="dialogTableVisible" :title="isEdit? '编辑应用':'创建应用'">
      <el-form :rules="rules" ref="formRef" :model="submitForm" label-width="120px">
        <el-form-item label="匹配根路径" prop="activeRule">
          <el-input placeholder="必须以'#/microApp/'开头" style="width: 260px;"
                    v-model.number="submitForm.activeRule"></el-input>
        </el-form-item>
        <el-form-item label="应用名称" prop="appName">
          <el-input placeholder="输入应用名称" style="width: 260px;" v-model="submitForm.appName"></el-input>
        </el-form-item>
        <el-form-item label="应用类型" prop="appType">
          <el-select
              placeholder="请选择应用类型"
              v-model="submitForm.appType"
              style="width: 260px;"
          >
            <el-option key="web" label="PC端" value="web"/>
            <el-option key="h5" label="手机H5" value="h5"/>
            <el-option key="miniapp" label="小程序" value="miniapp"/>
            <el-option key="nativeapp" label="手机APP" value="nativeapp"/>
          </el-select>
        </el-form-item>
        <el-form-item label="前端Ip" prop="frontIp">
          <el-input placeholder="输入前端Ip" style="width: 260px;" v-model="submitForm.frontIp"></el-input>
        </el-form-item>
        <el-form-item label="前端端口" prop="frontPort">
          <el-input placeholder="输入前端端口" style="width: 260px;" v-model.number="submitForm.frontPort"></el-input>
        </el-form-item>
        <el-form-item label="nginx根路径" prop="nginxBasePath">
          <el-input placeholder="输入nginx根路径" style="width: 260px;" v-model="submitForm.nginxBasePath"></el-input>
        </el-form-item>
        <el-form-item label="服务端Ip" prop="serverIp">
          <el-input placeholder="输入服务端Ip" style="width: 260px;" v-model="submitForm.serverIp"></el-input>
        </el-form-item>
        <el-form-item label="服务端端口" prop="serverPort">
          <el-input placeholder="输入服务端端口" style="width: 260px;"
                    v-model.number="submitForm.serverPort"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogTableVisible = false">取 消</el-button>
        <el-button type="primary" @click="newApp(formRef)">提 交</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import {onBeforeMount} from "vue";
import type {FormInstance} from 'element-plus';
import {
  ElMessage,
  ElMessageBox,
  ElLoading
} from 'element-plus';

import {
  editApp, EditAppArgs, delApp, adminGetAppList, exportAppSettingsInsertSql,
} from '@/service/AppManager';
import type {AppMo} from "@/service/entity/AppMo";
import {layoutStore} from '@/store/menu';
import {srvHost} from "@/config/Host";
import {getAdminToken} from "@/utils/setToken";

const store = layoutStore()

const total = ref(0)
const pageNo = ref(1)
const pageSize = ref(10)
const keyword = ref('')
const tableData = ref([])
const loading = ref(false)
let isEdit = ref(false)
let dialogTableVisible = ref(false)
const submitForm = reactive<EditAppArgs>({
  appId: "",
  activeRule: "",
  appName: "",
  appType: "",
  frontIp: "",
  frontPort: 0,
  nginxBasePath: "",
  serverIp: "",
  serverPort: 0
})
const formRef = ref<FormInstance>()
const rules = reactive({

  activeRule: [{
    required: true, message: '匹配根路径必填', trigger: 'blur'
  }],
  appName: [{
    required: true, message: '应用名称必填', trigger: 'blur'
  }],
  appType: [{
    required: true, message: '应用类型必填', trigger: 'blur'
  }],
  frontIp: [{
    required: true, message: '前端Ip必填', trigger: 'blur'
  }],
  frontPort: [{
    required: true, message: '前端端口必填', trigger: 'blur'
  }],
  serverIp: [{
    required: true, message: '服务端Ip必填', trigger: 'blur'
  }],
  serverPort: [{
    required: true, message: '服务端端口必填', trigger: 'blur'
  }]
})

onBeforeMount(() => {
  updata()
})

const onKeywordChange = (val: string) => {
  keyword.value = val
  updata()
}

const onClearKeyword = () => {
  keyword.value = ''
  updata()
}

const onSearch = async () => {
  updata()
}

const onReset = async () => {
  keyword.value = ''
  pageNo.value = 1
  pageSize.value = 10
  updata()
}

const onNew = async (row?: AppMo) => {
  if (row) {
    for (let key in row) {
      submitForm[key] = row[key]
    }
    submitForm['appId'] = row.id
    isEdit.value = true
  } else {
    for (let key in submitForm) {
      submitForm[key] = ''
    }
    isEdit.value = false
  }
  dialogTableVisible.value = true
}

const newApp = async (formRef: FormInstance | undefined) => {
  if (!formRef) {
    return
  }
  await formRef.validate(async (valid, fields) => {
    if (valid) {
      const res = await editApp({
        activeRule: submitForm.activeRule,
        appId: submitForm.appId,
        appType: submitForm.appType,
        appName: submitForm.appName,
        frontIp: submitForm.frontIp,
        frontPort: submitForm.frontPort,
        serverIp: submitForm.serverIp,
        serverPort: submitForm.serverPort
      })
      if (!res) return false
      formRef.resetFields()
      dialogTableVisible.value = false
      updata()
      ElMessage({
        type: 'success',
        message: '已提交'
      })
      return true
    } else {
      return false
    }
  })
}

const onExportSettings = async (id: number, appName: string) => {
  await exportAppSettingsInsertSql(id, appName);
}

const onDel = (id: number) => {
  ElMessageBox.confirm(
      '永久删除该条信息. 是否确认?',
      'Warning',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
      }
  )
      .then(async () => {
        const res = await delApp(id)
        if (res) {
          updata()
        }
      })
      .catch(() => {
        ElMessage({
          type: 'info',
          message: '取消删除',
        })
      })

}

async function updata() {
  loading.value = true
  try {
    const res = await adminGetAppList({pageNo: pageNo.value, pageSize: pageSize.value, keyword: keyword.value})
    tableData.value = res.arr
    total.value = res.total
  } finally {
    setTimeout(() => loading.value = false, 200)
  }
}

const handleSizeChange = (val: number) => {
  pageSize.value = val
  updata()
}
const handleNoChange = (val: number) => {
  pageNo.value = val
  updata()
}


let uploading;
const onImportSqlShellPre = () => {
  uploading = ElLoading.service({
    lock: true,
    text: 'Loading',
    background: 'rgba(0, 0, 0, 0.7)',
  })
}

const onImportSqlShellSucc = () => {
  if (uploading) {
    uploading.close();
  }
  ElMessage({
    type: 'success',
    message: '导入成功',
  })
}

const onImportSqlShellErr = () => {
  if (uploading) {
    uploading.close();
  }
  ElMessage({
    type: 'error',
    message: '导入失败',
  })
}

</script>

<style scoped lang="scss">
@import "@/global.scss";

.c-header {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  margin-bottom: 16px;
}

.tem-table {
  height: 100%;
  display: flex;
  flex-direction: column;
  box-shadow: var(--ap-box-shadow-light);
  box-sizing: border-box;
  padding: 10px;
}


.tem-table-box {
  flex: 1;
  overflow: hidden;
}
</style>